import GetLocation from '@/components/GetLocation/';
import Imagelocation from '@/components/Imagelocation';
import NavBar from '@/components/NavBar';
import utils from '@/utils/index';
import { sourceUrl } from '@/config';
import { regeo } from '@/dataTransfer/address';
import pSelected from '@/images/cart/selected.svg';
import pDisabled from '@/images/cart/disabled.png';
import pAddDisabled from '@/images/cart/addDisabled.png';
import pShop from '@/images/cart/shop.png';
import pTakeOut from '@/images/cart/takeOut.png';
import pUnselected from '@/images/cart/unselected.svg';
import addImage from '@/images/common/add.png';
import pBqTuancan from '@/images/common/bqTuancan.png';
import failImg from '@/images/common/fail.png';
import pLocation from '@/images/common/location.png';
import pLocationWhite from '@/images/common/locationWhite.png';
import subImage from '@/images/common/sub.png';
import pZhekou from '@/images/common/zhekou.png';
import pTo from '@/images/common/rightIn.png';
import { debounce, debounceDelay } from '@/utils/helper';
import { WrapPageLoadLoading } from '@/components/PageLoadLoading';
import { Button, Image, Text, View, Input } from '@tarojs/components';
import Taro, { useDidShow, useRouter } from '@tarojs/taro';
import React, { useEffect, useMemo, useState } from 'react';
import { connect } from 'react-redux';
import classNames from 'classnames';
import { checkProductIsSoldOut } from '@/dataTransfer/product';
import UnusualContain from '@/pages/mainPages/unusualContain/index';

import ScrollDelete from './scrollDelete';
import AddressSelect from '../addressSelect/index';
import MenuTabs from '../menuTabs/index';
import ImgCover from './imgCover';
import SoldButton from './soldButton';
import './index.scss';
import CartNum from '../cartNum';

const CartPage = ({
  dispatch,
  cartList,
  effectOrgList = [],
  uneffectOrgList = [],
  cartSelected,
  selectedAddress = {},
  cartNoMenu = false,
  noMenu = false,
}) => {
  const [curLocation, setCurLocation] = useState(null);
  const [curLocationAddr, setCurLocationAddr] = useState(null);
  const [showAddrList, setShowAddrList] = useState(false);
  const selectList = [...cartSelected];
  let urlParms = { isFromDetail: false };
  const router = useRouter();
  if (router) {
    urlParms.isFromDetail = cartNoMenu || noMenu;
  }

  // TODO: 待确认此次修改是否会产生其它问题
  const getLocationAddr = () => {
    regeo(curLocation)
      .then(({ address, adcode }) => {
        setCurLocationAddr(address);
        dispatch({
          type: 'productCar/setLocationAddress',
          payload: { ...curLocation, address: address },
        });

        setCurLocation({ ...curLocation, adCode: adcode });
      })
      .catch(console.warn);
  };

  const getList = () => {
    dispatch({
      type: 'productCar/getCartList',
      payload: { ...curLocation },
    });
  };

  useDidShow(() => {
    let unusualInfo = utils.getLocalStorage('unusualInfo');
    if (unusualInfo !== null) {
      utils.setLocalStorage('unusualInfo', null);
    }
    curLocation &&
      curLocation.latitude !== undefined &&
      selectedAddress.id === undefined &&
      false !== utils.getToken() &&
      getList();

    try {
      Taro.setTabbarIndex(1);
    } catch (e) {
      console.warn(e);
    }
  }, []);

  useEffect(() => {
    !urlParms.isFromDetail && Taro.setTabbarIndex(1, showAddrList);
  }, [showAddrList]);

  useEffect(() => {
    if (selectedAddress.id) {
      const { latitude, longitude, address, houseNumber } = selectedAddress;
      setCurLocation({ latitude, longitude, addressId: selectedAddress.id });
      setCurLocationAddr(address + houseNumber);
    }
  }, [selectedAddress]);

  useEffect(() => {
    curLocation &&
      curLocation.latitude !== undefined &&
      selectedAddress.id === undefined &&
      curLocation.adCode === undefined &&
      getLocationAddr();
  }, [curLocation]);

  useEffect(() => {
    curLocation && (curLocation.adCode || curLocation.addressId) && getList();
  }, [curLocation]);

  const openAddrList = () => {
    setShowAddrList(true);
  };

  const closeAddrList = () => {
    setShowAddrList(false);
  };

  let unusualInfo = utils.getLocalStorage('unusualInfo');

  useDidShow(() => {
    dispatch({
      type: 'productList/getCarNum',
      payload: {},
    });
  });

  return (
    <View className="totalPage-cart">
      {!Taro.$isH5 && <CartNum />}

      {!Taro.$isH5 && (
        <NavBar
          title="购物车"
          backgroundColor="#313A97"
          titleColor="#ffffff"
          showLeft={urlParms.isFromDetail}
          leftWhite
        >
          <View className="navBar-bg" />
        </NavBar>
      )}

      <AddressSelect isOpened={showAddrList} handleClose={closeAddrList} />

      <View className="fontPage">
        {unusualInfo ? (
          <UnusualContain unusualInfo={unusualInfo} />
        ) : (
          <View className="contentPage">
            <View className={classNames('homePage', { weapp: !Taro.$isH5 })}>
              {selectedAddress.id === undefined && <GetLocation handleLocation={setCurLocation} />}
              {cartList === null && false === utils.getToken() && (
                <View className={classNames('content-cart-empty', { h5: Taro.$isH5 })}>
                  <View className="empty-cart">
                    <Image
                      src="https://ht-fine-static.oss-cn-beijing.aliyuncs.com/weapp/aNeedUp/gouwuche_kong.png"
                      className="icon"
                    />
                    <View
                      className="info"
                      onClick={() => {
                        Taro.navigateTo({
                          url: '/pages/other/login/index',
                        });
                      }}
                    >
                      暂无信息，请点击
                      <View className="infosp">登录</View>～
                    </View>
                  </View>
                </View>
              )}

              {cartList &&
                effectOrgList.length === 0 &&
                uneffectOrgList.length === 0 &&
                curLocation !== null && (
                  <View className={classNames('content-cart-empty', { h5: Taro.$isH5 })}>
                    <View className="empty-cart">
                      <Image
                        src="https://ht-fine-static.oss-cn-beijing.aliyuncs.com/weapp/aNeedUp/gouwuche_kong.png"
                        className="icon"
                      />
                      <View className="info">暂无商品，快去逛逛吧～</View>
                    </View>
                  </View>
                )}
              {(effectOrgList.length > 0 || uneffectOrgList.length > 0) && (
                <View className="content-cart">
                  <View className="location" onClick={openAddrList}>
                    <Image className="icon" src={Taro.$isH5 ? pLocation : pLocationWhite} />
                    <Text className="txt">
                      {curLocationAddr ? '配送至：' + curLocationAddr : '请选择地址'}
                    </Text>
                  </View>
                  {effectOrgList.length > 0 &&
                    effectOrgList.map((org, index) => (
                      <OrgView
                        key={org.orgId + '_act' + index}
                        orgGoods={org}
                        dispatch={dispatch}
                        selectList={selectList}
                        curLocation={curLocation}
                        isFromDetail={urlParms.isFromDetail}
                      />
                    ))}
                  {uneffectOrgList.length > 0 && (
                    <View className="split">
                      <View className="line"></View>
                      <View className="txt">超出配送范围</View>
                      <View className="line"></View>
                    </View>
                  )}
                  {uneffectOrgList.length > 0 &&
                    uneffectOrgList.map((org, index) => (
                      <OrgView
                        key={org.orgId + '_un' + index}
                        orgGoods={org}
                        dispatch={dispatch}
                        selectList={selectList}
                        curLocation={curLocation}
                        isFromDetail={urlParms.isFromDetail}
                        unOpt
                      />
                    ))}
                </View>
              )}
            </View>
          </View>
        )}
      </View>

      {!urlParms.isFromDetail && <MenuTabs tabIndex={1} />}
    </View>
  );
};

const OrgView = ({
  dispatch,
  orgGoods = [],
  selectList,
  curLocation,
  isFromDetail = false,
  unOpt = false,
}) => {
  const { products: productsProps = [] } = orgGoods;
  // 组件内维护状态 STAR
  const [products, setProducts] = useState(productsProps);
  useEffect(() => {
    setProducts([...productsProps]);
  }, [productsProps]);
  // 组件内维护状态 end

  const shopSelected = products.filter((v) => selectList.includes(v.id));
  const totalPrice = shopSelected.reduce((pre, cur) => {
    return pre + cur.price * 100 * cur.num;
  }, 0);
  const handleSetGoodNum = (newNum, goods) => {
    const goodIndex = products.indexOf(goods);
    setProducts(
      products.map(({ num: oldNum, ...productsGood }, index) => ({
        ...productsGood,
        num: index === goodIndex ? newNum : oldNum,
      })),
    );
  };
  const handlePurchaseNum = (newNum = 0, goods) => {
    let { num: oldNum, id, favouredType, activityLimit, inventoryQuantity } = goods;
    const type = newNum > oldNum ? 'add' : 'sub';
    if (type === 'add') {
      if (newNum > parseInt(inventoryQuantity)) {
        handleSetGoodNum(parseInt(inventoryQuantity), goods);
        handleAsyncGoodsNum(id, parseInt(inventoryQuantity));
        Taro.showToast({
          title: '数量修改失败，超出库存！',
          icon: 'none',
          mask: false,
          duration: 1500,
        });

        return false;
      }

      if (favouredType == 3 && activityLimit > 0 && newNum == parseInt(activityLimit) + 1) {
        Taro.showToast({
          title: '该折扣商品限购' + activityLimit + '份,超过' + activityLimit + '份恢复原价',
          icon: 'none',
          mask: false,
          duration: 1500,
        });
      }
    }
    if (type === 'sub' && newNum < 1) {
      handleSetGoodNum(1, goods);
      handleAsyncGoodsNum(id, 1);
      return;
    }

    handleSetGoodNum(newNum, goods);
    handleAsyncGoodsNum(id, newNum);
  };

  const handleAsyncGoodsNum = useMemo(
    () =>
      debounceDelay(async (id, num) => {
        await dispatch({
          type: 'productCar/updateProductNum',
          payload: { id, num },
        });
        await dispatch({
          type: 'productCar/getCartList',
          payload: { ...curLocation },
        });
      }, 500),
    [],
  );

  const handleDelProduct = debounce(async (goods) => {
    let { id } = goods;
    await dispatch({ type: 'productCar/deleteDeleteProduct', payload: { id } });
    await dispatch({
      type: 'productCar/getCartList',
      payload: { ...curLocation },
    });
  }, 300);

  const shopAllSelected = (productsList) => {
    const goodsIds = productsList.reduce((pre, cur) => {
      return pre.concat(cur.id);
    }, []);

    const intersection = selectList.filter((v) => goodsIds.includes(v));
    return intersection.length === goodsIds.length;
  };

  const checkGoods = (goodsId) => {
    const selList = [...selectList];
    const index = selList.indexOf(goodsId);
    if (index === -1) {
      dispatch({
        type: 'productCar/setCartSelect',
        payload: [...selList, goodsId],
      });
    } else {
      selList.splice(index, 1);
      dispatch({
        type: 'productCar/setCartSelect',
        payload: selList,
      });
    }
  };

  const addAll = (goodsIds) => {
    dispatch({
      type: 'productCar/setCartSelect',
      payload: Array.from(new Set([...selectList, ...goodsIds])),
    });
  };
  const removeAll = (goodsIds = []) => {
    const selList = selectList.filter((v) => !goodsIds.includes(v));
    dispatch({
      type: 'productCar/setCartSelect',
      payload: selList,
    });
  };
  const handleToggleShop = (productsList) => {
    const goodsIds = productsList.reduce((pre, cur) => {
      return pre.concat(cur.id);
    }, []);

    let intersection = selectList.filter((v) => goodsIds.includes(v));
    if (intersection.length < goodsIds.length) {
      addAll(goodsIds);
    } else {
      removeAll(goodsIds);
    }
  };

  const toShopDetail = (orgId, merchantId, type) => {
    if (type == 1) {
      //商城跳到商城商品主页
      Taro.navigateTo({
        url: `/mainSubPack/shoppingMall/index?orgId=${orgId}&merchantId=${merchantId}`,
      });
    } else if (type == 4) {
      //外卖跳到外卖店铺
      Taro.navigateTo({
        url: `/mainSubPack/takeOutShop/index?orgId=${orgId}&merchantId=${merchantId}`,
      });
    }
  };

  const toGoodsDetail = (orgId, merchantId, type, product) => {
    let { productReleaseId, favouredId } = product;
    if (type == 1) {
      //商城商品跳到商品详情
      product.id = productReleaseId;
      product.activityId = favouredId;
      utils.goGoodDetail(product, dispatch);
    } else if (type == 4) {
      //外卖商品跳到外卖店铺
      Taro.navigateTo({
        url: `/mainSubPack/takeOutShop/index?orgId=${orgId}&merchantId=${merchantId}`,
      });
    }
  };

  const handlePurchase = () => {
    if (shopSelected.length === 0) {
      return Taro.showToast({
        mask: true,
        title: '最少购买1件',
        image: failImg,
        duration: 1000,
      });
    }
    let ids = shopSelected.map((v) => v.id);
    dispatch({
      type: 'productCar/setCartShopSelected',
      payload: ids,
    });
    Taro.navigateTo({
      url: `/orderSubPack/confirmOrder/index?orgId=${orgGoods.orgId}&merchantId=${orgGoods.merchantId}&type=${orgGoods.type}`,
    });
  };

  return (
    <View className={['orgView', isFromDetail && 'unBottom'].join(' ')}>
      {unOpt && <View className="mask"></View>}
      <View className="orgTitle">
        <View className="title line">
          <Image className="orgIcon" src={orgGoods.type == 1 ? pShop : pTakeOut} />
          <View
            className="orgName"
            onClick={() => toShopDetail(orgGoods.orgId, orgGoods.merchantId, orgGoods.type)}
          >
            <Text className="txt">{orgGoods.orgName || ''}</Text>
            <Image className="toIcon" src={pTo} />
          </View>
          {orgGoods.distributionWayStr?.length > 0 && (
            <View className={['type', orgGoods.type == 1 ? 'shop' : 'waimai'].join(' ')}>
              {orgGoods.distributionWayStr}
            </View>
          )}
        </View>
        {orgGoods.policy && orgGoods.policy.length > 0 && (
          <View className="activity line">
            {orgGoods.policy.map((item, index) => (
              <Text className="manjian" key={'manjian' + orgGoods.created + index}>
                {item}
              </Text>
            ))}
          </View>
        )}
      </View>
      <View className="goods">
        {products.length > 0 &&
          products
            .sort((a, b) => a.id - b.id)
            .map((good, gIdx) => {
              const currentSelect = selectList.includes(good.id);
              let optionSelObj = JSON.parse(good.optionValue);
              let selOptionList = [];
              for (let key in optionSelObj) {
                selOptionList.push(optionSelObj[key]);
              }

              // 商品此地区无货
              const isDeliveryDisabled = good?.deliveryStatus === 2;

              return (
                <ScrollDelete key={good.id + '_' + orgGoods.created + '_' + gIdx}>
                  <View className={['goodInfo', gIdx == 0 && 'first'].join(' ')}>
                    <Image
                      className="selectIcon"
                      src={
                        currentSelect
                          ? pSelected
                          : // 已售罄 或者 活动已结束 或者 此地区无货
                          checkProductIsSoldOut(good, 'inventoryQuantity') ||
                            good.favouredStatus === '2' ||
                            isDeliveryDisabled
                          ? pDisabled
                          : pUnselected
                      }
                      onClick={() => checkGoods(good.id)}
                    />
                    <View
                      className="imgArea"
                      onClick={() =>
                        toGoodsDetail(orgGoods.orgId, orgGoods.merchantId, orgGoods.type, good)
                      }
                    >
                      {good.favouredStatus === '2' ? (
                        <ImgCover txt="已结束" />
                      ) : checkProductIsSoldOut(good, 'inventoryQuantity') ? (
                        <ImgCover txt="已售罄" />
                      ) : isDeliveryDisabled ? (
                        <ImgCover txt="已售罄" />
                      ) : null}

                      <Imagelocation
                        className="gIcon"
                        src={
                          good.productReleaseImg.indexOf('http') === 0
                            ? good.productReleaseImg
                            : sourceUrl + good.productReleaseImg
                        }
                      />
                      {good.favouredType == 1 && <Image className="bqImg" src={pBqTuancan} />}
                      {good.favouredType == 3 && <Image className="bqImg zhekou" src={pZhekou} />}
                    </View>
                    <View className="goodBase">
                      <View className="goodName">{good.productReleaseTitle}</View>
                      <View className="goodSku">{selOptionList.join('/')}</View>
                      {good.distributionWayList && good.distributionWayList.length > 0 && (
                        <View className="goodSend">
                          {good.distributionWayList
                            .sort((a, b) => a - b)
                            .map((dbway) => {
                              if (dbway == '1') {
                                return (
                                  <View
                                    className="send blue"
                                    key={good.id + '_' + orgGoods.created + '_' + dbway}
                                  >
                                    直邮
                                  </View>
                                );
                              } else if (dbway == '2') {
                                return (
                                  <View
                                    className="send red"
                                    key={good.id + '_' + orgGoods.created + '_' + dbway}
                                  >
                                    外送
                                  </View>
                                );
                              } else if (dbway == '3') {
                                return (
                                  <View
                                    className="send green"
                                    key={good.id + '_' + orgGoods.created + '_' + dbway}
                                  >
                                    自提
                                  </View>
                                );
                              }
                            })}
                        </View>
                      )}
                      {good.favouredType == 3 && (
                        <View className="activity">
                          <View className="zhekou-icon">限时折扣</View>
                          <Text className="discount">
                            {good.discount}
                            {good.favouredStatus !== '2' ? '折' : ''}
                          </Text>
                          <Text className="activityLimit">
                            {good.activityLimit == 0 || good.activityLimit === undefined
                              ? ''
                              : '限' + good.activityLimit + '份'}
                          </Text>
                        </View>
                      )}
                      {(!good.distributionWayList || good.distributionWayList.length == 0) &&
                        good.favouredType != 3 && <View className="activity"></View>}
                      <View className="goodPrice">
                        <View className="price">
                          <Text className="zNum">¥{good.price}</Text>
                          {good.favouredType == 3 && good.favouredStatus !== '2' && (
                            <Text className="middle">¥{good.cost}</Text>
                          )}
                        </View>

                        {good.favouredStatus === '2' ? (
                          <SoldButton txt="活动已结束" />
                        ) : checkProductIsSoldOut(good, 'inventoryQuantity') ? (
                          <SoldButton txt="已售罄" />
                        ) : isDeliveryDisabled ? (
                          <SoldButton txt="已售罄" />
                        ) : (
                          <View className="number-sel">
                            <Image
                              mode="widthFix"
                              className="sub"
                              src={subImage}
                              onClick={() => handlePurchaseNum(good.num - 1, good)}
                            />
                            <Input
                              className="num"
                              type="number"
                              maxlength={4}
                              value={good.num}
                              placeholderStyle="color:#E5E5E5"
                              onBlur={(e) => {
                                let value = e.detail.value || 0;
                                value = parseInt(value + '');
                                handlePurchaseNum(value, good);
                              }}
                            />
                            <Image
                              mode="widthFix"
                              className="add"
                              src={
                                good.num >= parseInt(good.inventoryQuantity)
                                  ? pAddDisabled
                                  : addImage
                              }
                              onClick={() => handlePurchaseNum(good.num + 1, good)}
                            />
                          </View>
                        )}
                      </View>
                    </View>
                  </View>
                  <View className="del-btn" onClick={() => handleDelProduct(good)}>
                    <Text className="text">删除</Text>
                  </View>
                </ScrollDelete>
              );
            })}
      </View>
      {!unOpt && (
        <View className="bottom">
          <View className="left">
            <View className="checkedAll" onClick={() => handleToggleShop(products)}>
              <Image className="sIcon" src={shopAllSelected(products) ? pSelected : pUnselected} />
              <Text className="sText">全选</Text>
            </View>
            <Text className="tText">合计</Text>
            <Text className="tCount">
              <Text className="unit">¥</Text>
              {(totalPrice / 100).toFixed(2)}
            </Text>
          </View>
          <Button className="right" onClick={() => handlePurchase()}>
            去结算
          </Button>
        </View>
      )}
    </View>
  );
};

export default connect(({ loading, productCar, otherApi }) => ({
  cartList: productCar.cartList,
  effectOrgList: productCar.effectOrgList,
  uneffectOrgList: productCar.uneffectOrgList,
  cartSelected: productCar.cartSelected,
  selectedAddress: productCar.selectedAddress,
  cartNoMenu: otherApi.cartNoMenu,
  loading,
}))(WrapPageLoadLoading(CartPage, { page: 'cart', once: true }));
